package com.study.dimensionreduction

import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.linalg.distributed.RowMatrix
import org.apache.spark.sql.SparkSession

/**
 * 降维-奇异值分解（Singular Value Decomposition，SVD）
 *
 * @author stephen
 * @date 2019-08-29 14:51
 */
object SVDDemo {

  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder()
      .appName(this.getClass.getSimpleName)
      .master("local[*]")
      .getOrCreate()

    spark.sparkContext.setLogLevel("warn")
    // RDD
    val data = spark.sparkContext.parallelize(Array(
      Vectors.dense(1.0, 2.0, 3.0, 4.0, 5.0),
      Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0),
      Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0)
    ))
    // 通过RDD[Vectors]创建行矩阵
    val ma = new RowMatrix(data)
    // 保留前3个奇异值 Am×n≈Um×k∗Sk×k∗V′n×k
    val svd = ma.computeSVD(3, true)
    // 右奇异矩阵 Um×k
    println("========= Um×k ========")
    svd.U.rows.foreach(println)
    // 奇异值向量 Sk×k
    println("========= Sk×k ========")
    println(svd.s)
    // 左奇异矩阵 V′n×k
    println("========= V′n×k ========")
    println(svd.V)

    spark.stop()
  }
}
